کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

برنامه اندروید و Activity

این مبحث به شرح life cycle یا چرخه ی حیات اپلیکیشن و activity در اندروید می پردازد.

مدیریت چرخه ی حیات / lifecycle اپلیکیشن

در شرایط ایده ال، کلیه ی اپلیکیشن هایی که کاربر در دستگاه اندروید خود راه اندازی می کند، باید در حافظه باقی بمانند. نا گفته پیدا است که این امر در تسریع راه اندازی مجدد اپلیکیشن بسیار موثر است. اما حقیقت امر این است که حافظه ی دستگاه اندروید همانند اندازه ی خود دستگاه، کوچک بوده و دارای ظرفیت محدود می باشد. به منظور مدیریت بهینه ی این منابع محدود سیستم اندروید این اجازه را دارد که فرایندهای در حال اجرا را متوقف کرده یا کامپوننت های اندروید را بازیابی (recycle) کند.
در صورتی که سیستم اندروید به این منابع نیاز داشته باشد، طبیعتا باید این منابع را آزاد کند. برای آزاد کردن این منابع از تعدادی قانون ساده پیروی می کند. در واقع هر فرایند در حال اجرا دارای اولویتی است که اندروید آن ها را بر اساس این اولویت از حافظه پاک می کند.

Table 1. Priorities
اولویت
شرح
وضعیت فرایند/process status
1
اپلیکیشنی که کاربر در حال تعامل با activity آن می باشد یا دارای سرویسی است که به این activity متصل است. همچنین سرویسی که در حال اجرای یکی از متدهای مدیریت چرخه ی حیات (lifecycle method) بوده یا broadcast receiver ای که در حال فراخوانی و اجرای متد onReceive() خود می باشد.
Foreground/پیش زمینه
2
کاربر دیگر با activity تعامل ندارد، اما activity هنوز (تا اندازه ای) قابل مشاهده است یا اپلیکیشن مورد نظر سرویسی دارد که توسط activity قابل مشاهده اما غیرفعال مورد استفاده قرار می گیرد.
قابل مشاهده/Visible
3
اپلیکیشن با یک سرویس در حال اجرا که ویژگی های 1 یا 2 را ندارد.
Service
4
اپلیکیشنی که تمامی activity های آن متوقف شده و هیچ سرویس یا دریافت کننده ای ندارد. سیستم اندروید تمامی آن ها را در یک لیست LRU نگه داشته و در صورت لزوم آن هایی که از تاریخ آخرین بار استفاده ی آن خیلی می گذرد یا کم ترین استفاده را داشته اند را از حافظه حذف می کند.
Background/پس زمینه
5
اپلیکیشنی که هیچ کامپوننت در حال اجرا و فعالی ندارد.
Empty

مامی فرایندهایی که از اولویت 6 برخوردار هستند (در رده ی "Empty" قرار می گیرند) به لیست LRU اضافه می شوند و فرایندهایی که در ابتدای این لیست ها قرار دارند، توسط out of memory killer نابود می شوند (برای آزاد سازی منابع از حافظه حذف می شوند). حال چنانچه اپلیکیشنی توسط کاربر مجددا راه اندازی شد، آن اپلیکیشن به انتهای صف هدایت می شود و اولویت آن به 1 تغییر می یابد. این جریان در تصویر زیر به نمایش گذاشته شده است:

مدیریت چرخه ی حیات / lifecycle اپلیکیشن

فراخوانی متد get() برای یک آیتم سبب می شود آن آیتم به انتهای حافظه ی LRU (cache) انتقال یابد.

آبجکت application

هر زمان که یک کامپوننت راه اندازی می شود، سیستم اندروید به صورت خودکار یک آبجکت application ایجاد می کند که این آبجکت تحت یک فرایند جدید با ID منحصربفرد و مختص به یک کاربر خاص ایجاد می شود. حتی اگر برنامه نویس آبجکت application را در فایل تنظیمات (AndroidManifest.xml)، در تگ application مشخص نکند، سیستم اندروید به صورت پیش فرض یک نمونه از کلاس Application (همان آبجکت application) ایجاد می کند (این آبجکت بیشتر برای نگهداری وضعیت و اطلاعات سراسری اپلیکیشن مورد استفاده قرار می گیرد).
آبجکت ذکر شده یک سری توابع مربوط به مدیریت lifecycle ارائه می دهد که در زیر به هریک همراه با عملکرد آن اشاره می کنیم:

  • onCreate() – این متد قبل از اینکه اولین کامپوننت های اپلیکیشن راه اندازی شوند، فراخوانی می گردد. به عبارت دیگر این متد یک تابع callback است و هنگامی که activity برای نخستین بار اجرا می شود، فراخوانی می گردد.
  • onLowMemory() – زمانی صدا خورده می شود که کل سیستم با کمبود حافظه مواجه شده و فرایندهای در حال اجرا یا فعال می بایست میزان استفاده ی خود از حافظه را کاهش دهند. سیستم اندروید با فراخوانی این تابع به اپلیکیشن دستور می دهد که باید حافظه را بهینه استفاده کرده و میزان استفاده ی خود را تا حد امکان محدود کند. شما این متد را بایستی زمانی پیاده سازی کنید که لازم باشد cache یا دیگر منابع غیر ضروری که برنامه اشغال کرده را آزاد سازی نمایید.
  • onTrimMemory() – این متد زمانی صدا خورده می شود که سیستم عامل احساس کند که فرایند باید میزان استفاده ی خود از حافظه را کاهش دهد. این اتفاق (برای مثال) زمانی می افتد که فرایند در وضعیت background قرار گرفته باشد و در این میان حافظه ی کافی برای فعال نگه داشتن تعداد دلخواه فرایند پس زمینه ای وجود ندارد. به عبارت دیگر، این متد زمانی فراخوانده می شود که سیستم اندروید از اپلیکیشن درخواست استفاده ی بهینه از حافظه/کاهش استفاده از آن را داشته باشد. این متد پارامترهایی دارد که از وضعیت جاری اپلیکیشن خبر می دهند. برای مثال، ثابت TRIM_MEMORY_MODERATE بیانگر این است که فرایند در اواسط لیست LRU قرار دارد. در این شرایط طبیعتا آزاد سازی حافظه به سیستم کمک می کند تا دیگر فرایندهای در حال اجرا را جهت بهبود کارایی کلی سیستم، در انتهای لیست مذکور نگه دارد.
  • onTerminate() – تنها به منظور تست در محیط شبیه ساز بکار رفته و به هیچ وجه در بستر اجرا نهایی (محیط production) اپلیکیشن فراخوانی نمی شود.
  • onConfigurationChanged() – این متد زمانی فراخوانده می شود که کامپوننت شما در حال اجرا است و در این حین تنظیمات و configuration دستگاه تغییر می کند.

ازم به توضیح است که آبجکت application قبل از راه اندازی هر کامپوننتی ایجاد شده و حداقل تا زمانی که کامپوننت دیگری از اپلیکیشن راه اندازی نشده، به اجرا ادامه می دهد.

خاصیت Border در CSS

هر زمان که content provider مورد دسترسی قرار می گیرد، این کامپوننت هیچگاه به صورت انفرادی و جداگانه متوقف نمی شود. به بیانی روشنتر این کامپوننت تنها زمانی کاملا متوقف می شود که کل فرایند اپلیکیشن خاتمه یابد.

Lifecycle/چرخه ی حیات Activity

وضعیت های مختلف یک activity

یک Activity می تواند بسته به نحوه ی تعاملی که کاربر با آن دارد، در وضعیت های متفاوت قرار داشته باشد. این وضعیت ها در جدول زیر تشریح شده است:

Table 2. Activity state
شرح
وضعیت/state
در این وضعیت، activity کاملا قابل مشاهده بوده و کاربر می تواند با آن مستقیما تعامل داشته باشد.
Running
(در حال اجرا و قابل تعامل مستقیم)
Activity is still visible but partially obscured, instance is running but might be killed by the system.
در این وضعیت، Activity همچنان قابل مشاهده است ، اما نه به طور کامل و به اصطلاح دیگر در foreground قرار ندارد. در واقع نمونه در حال اجرا است، اما ممکن است سیستم اندروید آن را از حافظه پاک کند (kill).
Paused
(متوقف شده اما همچنان قابل رویت)
Activity is not visible, instance is running but might be killed by the system.
Activity قابل مشاهده نیست، نمونه در حال اجرا است اما ممکن است توسط سیستم از حافظه پاک شود.
Stopped
(متوقف شده و غیر قابل رویت)
Activity has been terminated by the system of by a call to its finish() method.
در این وضعیت سیستم اندروید متد finish() را صدا زده و activity مورد نظر در پی اجرای شدن این متد از حافظه پاک شده است.
Killed (کاملا نابود یا به اصطلاح از حافظه پاک شده است)

در نمودار زیر چرخه ی حیات یک activity را به همراه متدهای مهم آن مشاهده می کنید.

وضعیت های مختلف یک activity

لازم به ذکر است که اندروید متدهای دیگری نیز جهت چرخه ی حیات در اختیار دارد، اما موارد استفاده از آن ها نادر است. به عنوان مثال می توان به متد onDestroy() اشاره کرد.

پایان یافتن activity ها توسط سیستم عامل

سیستم اندروید این اجازه را دارد که در راستای بهبود کارایی و بهینه سازی سرعت، با recycle کردن activity ها (استفاده ی مجدد)، منابعی را آزاد کند. گفته می شود که سیستم عامل اندروید می تواند activity ها را فارغ از کل فرایند اپلیکیشن (به صورت منفرد) خاتمه دهد، در حالی که واقعیت چیز دیگری است. سیستم اندروید هیچگاه activity های فردی را recycle نمی کند، بلکه کل فرایند را بر اساس قوانین مشخص پایان می دهد.

توجه:

این یک باور غلط است که اندروید activity های منفرد را از حافظه پاک می کند. متاسفانه این توضیح اشتباه در سایت رسمی توسعه اندروید نیز ذکر شده است. اما بنا به گفته ی Dianne Hackborn که عضو تیم طراحان و توسعه دهندگان اندروید، بخش پیاده سازی out of memory killer هست، اندروید هیچگاه activity ها را به صورت منفرد خاتمه نمی دهد، بلکه کل فرایند میزبان activity ها را پایان می دهد.

توجه:

یک activity برای اینکه اطلاعات و وضعیت خود را به درستی ذخیره کرده و بعده ها بتواند آن را بازیابی کند، ناگذیر است اطلاعات state را در زمان مناسب ذخیره کند. همچنین، در صورتی که activity های غیر ضروری دیگر قابل مشاهده یا دسترسی نبودند، می بایست عملیات غیر ضروری را به منظور صرفه جویی در منابع سیستم متوقف کند.

برای متوقف کردن listener های framework (گوش فراخوان ها) و بروز رسانی های UI، می بایست متد onPause() را فراخوانی کرده و سپس با استفاده از متد onStop() داده های اپلیکیشن را ذخیره نمایید. دو تابع نام برده حتما پیش از خاتمه یافتن activity صدا خورده می شوند. با فراخوانی onResume() می توانید دوباره listener ها را تخصیص داده و در صورت لزوم، بروز رسانی های UI را بر اساس داده های ذخیره شده از سر بگیرید (مجددا راه اندازی نمایید).
علاوه بر مدیریت منابع (resource management)، اندروید می بایست activity ها را در صورت رخداد تغییر در تنظیمات دستگاه، از نو ایجاد کند. آبجکت Configuration دربردارنده ی تنظیمات و پیکربندی جاری دستگاه می باشد. اگر این تنظیمات تغییر کند، activity های مجددا راه اندازی می شوند چرا که لازم است برای این تنظیمات جدید از منابع/resource متفاوت استفاده کنند.

داده ها و اطلاعات ذخیره شده از آبجکت activity جهت بازگردانی activity به وضعیت قبلی/ Activity instance state

همان طور که در بالا ذکر شد، هنگامی تنظیمات دستگاه تغییر می کند، مثلا وضعیت و جهت نمایش تغییر می یابد، activity برای اینکه متناسب با تنظیمات جدید نمایش داده شود، باید مقادیر و منابع متفاوتی را بخواند و از اینرو از نو ساخته می شود (ابتدا متد onDestroy()صدا خورده و بلافاصله متد onCreate() فراخوانی می شود). حال به منظور اینکه سیستم اندروید بتواند activity را با تنظیمات جدید، اما وضعیت قبلی بازگردانی کند، ناچار نمونه ای از آن کلاس را ذخیره می کند. سپس بر اساس داده های ذخیره شده، activity را به حالت قبلی بازمی گرداند. Instance state در واقع داده های موقتی و غیر ماندگار هستند که باید در بازه ی زمانی تغییر بین دو وضعیت نمایش (برای مثال بخاطر تغییر در تنظیمات دستگاه) بین activity ها (نمونه ی ذخیره شده از activity و نمونه ی مجدد ایجاد شده) پاس داده شود تا اطلاعات و انتخاب های کاربر (اینک با تنظیمات جدید) به حالت قبل بازگردانی شود. این اپلیکیشن است که وظیفه ی بازگردانی خود به حالت قبلی را دارد.
Instance state معمولا جفت های کلید-مقدار هستند که از activity خاتمه یافته، در آبجکت Bundle ذخیره می شوند و جهت بازگردانی وضعیت activity به حالت قبلی (وضعیتی که کاربر در آن اپلیکیشن را ترک کرد) مورد استفاده قرار می گیرند.
سناریویی را در نظر بگیرید که کاربر با نوار پیمایش به پایین یک لیست می رود (ListView) که در آن هزاران آیتم وجود دارد و در این میان activity حذف و مجددا ساخته می شود. طبیعتا کاربر دوست ندارد موقعیت جاری خود را در این لیست بسیار بزرگ از دست بدهد و دوباره مجبور به پیدا کردن آن شود. از اینرو موقعیت جاری کاربر باید حفظ شده و پس از ایجاد activity دوباره کاربر به آن بازگردانده شود.
برای این منظور متد onSaveInstanceState() صدا خورده شده و وضعیت نمونه را در قالب یک آبجکت Bundle در خود ذخیره می کند. آبجکت Bundle می تواند انواع داده ی اولیه، آرایه، رشته/String و Object هایی از جنس Parcelable و Serialisable را در خود ذخیره کند.
داده های ذخیره شده در کلاس Bundle، در زمان راه اندازی مجدد activity مورد نظر به عنوان پارامتر به متدهای onCreate() و onRestoreInstanceState() ارسال می شوند.
در صورت بازنویسی (override) پیاده سازی توابع onSaveInstanceState() و onRestoreInstanceState()، لازم است پیاده سازی کلاس پدر (super implementation) را نیز فراخوانی نمایید زیرا view های پیش فرض اندروید داده های خود را به واسطه ی فراخوانی View.onSaveInstanceState از متد onSaveInstanceState() ذخیره می کنند. برای مثال، EditText محتوای خود را از طریق فراخوانی پیش فرض این متد ذخیره می کند.
با استفاده از دو تابع onRestoreInstanceState() و onCreate() می توانید instance state یک activity را (در صورتی که activity نابود شده و مجددا ساخته شد) بازسازی نمایید.

توجه:

برای بازگردانی وضعیت activity (بازیابی instance state) توصیه می کنیم از متد onRestoreInstanceState() استفاده نمایید. این روش تنظیم و راه اندازی اولیه activity را از بازگردانی وضعیت آن به حالت قبلی (instance state) جدا می سازد.

اگر کاربر با activity تعامل داشته و سپس دکمه ی Back را فشار دهد یا اینکه متد finish() آن activity صدا خورده شود، activity مورد نظر از پشته ی جاری activity ها حذف شده و recycle می شود. در چنین شرایطی، هیچ instance state (داده ی ذخیره شده ای از وضعیت activity وجود ندارد که بخواهد بازگردانی شود) برای بازگردانی وجود ندارد، از اینرو متد onSaveInstanceState() هیچگاه فراخوانی نمی شود.
حال چنانچه کاربر با activity تعامل داشته و بعد دکمه ی Home را فشار دهد، اطلاعات مربوط به وضعیت activity / activity instance می بایست ذخیره شود. در پی این رخداد، متد onSaveInstanceState() فراخوانده می شود و اطلاعات مربوط به وضعیت activity را در خود ذخیره می کند. اکنون اگر کاربر به اپلیکیشن بازگردد یا به عبارتی آن را مجددا راه اندازی کند، سیستم عامل اندروید آخرین activity که هنگام ترک اپلیکیشن فعال و در حال اجرا بود را فراخوانی می کند. در واقع زمانی که activity مجددا راه اندازی می شود، آبجکت Bundle (حامل داده های ذخیره شده از وضعیت activity) در اختیار متدهای onRestoreInstanceState() و onCreate() قرار می گیرد.

توجه:

در صورتی که کاربر دکمه ی بازگشت را فشار دهد، متد onSaveInstanceState() صدا زده نمی شود. توجه داشته باشید که از این روش نباید به هیچ وجه برای ذخیره ی داده هایی که می بایست ماندگار شوند، استفاده نمایید.

مدیریت configuration و تنظیمات

جلوگیری از نابود و مجدد ایجاد شدن activity بر اثر تغییر در تنظیمات و وضعیت برنامه

همان طور که در بالا ذکر شد، activity بر اثر تغییر در تنظیمات و وضعیت دستگاه (config change) از بین رفته و جهت تطبیق با تنظیمات جدید و همچنین بارگذاری resource های جدید، دوباره ساخته می شود.
تغییر در تنظیمات ممکن است به دنبال یک event که از خود دستگاه اندروید اعلان یا صادر می شود و مربوط به برنامه ی جاری می باشد، اتفاق بیافتد.
اطلاعات مربوط به تنظیمات جاری دستگاه در نمونه ای از کلاس Configuration ذخیره می شود. در واقع Configuration یک کلاس است که تمامی اطلاعات مربوط به تنظیمات جاری دستگاه را تعریف می کند و این اطلاعات می توانند منابع و محتوای مورد نیاز اپلیکیشن را تحت تاثیر قرار دهند. کلاس مزبور هم می تواند تنظیمات تعریف شده توسط کاربر (همچون locale list و scaling = مقیاس بندی به صورت پویا) را شامل شود و هم تنظیمات دستگاه نظیر حالت دریافت ورودی (input mode)، اندازه ی صفحه یا وضعیت و جهت نمایش.
به عنوان مثال زمانی که کاربر با چرخاندن دستگاه، وضعیت نمایش و چیدمان را تغییر می دهد (از نمای عمودی به افقی تغییر می دهد)، در این هنگام سیستم اندروید متوجه می شود که activity جهت تطبیق با شرایط جاری، لازم به بارگذاری منابع جدید دارد. از اینرو activity کنونی را نابود کرده و بار دیگر با تنظیمات جدید آن راه اندازی می کند.
هنگامی که activity نابود و مجدد ساخته می شود، برنامه نویس می بایست اطمینان حاصل کند که نمونه ی جدید activity با اطلاعات مربوط به وضعیت قبلی ایجاد و بارگذاری شود. سیستم اندروید ابزار و روش های مختلفی برای این منظور ارائه می دهد. در محیطemulator می توانید با فشردن کلیدهای Ctrk+F11 به راحتی تغییر در وضعیت و جهت نمایش را شبیه سازی نمایید.
می توانید activity را طوری در فایل XML تعریف کنید که نسبت به برخی از تغییرات در وضعیت و تنظیمات بی تفاوت باشد و به تبع از راه اندازی مجدد activity در موارد مزبور جلوگیری نمایید. کافی است در فایل تنظیمات AndroidManifest.xml خود، داخل تگ activity، خصیصه (attribute) configChanges را با مقدار مربوطه تنظیم نمایید.
Activity زیر طوری تنظیم شده که در صورت رخداد تغییر در وضعیت نمایش یا موقعیت صفحه کلید (قابل مشاهده/پنهان)، از نو راه اندازی نشود و به بیانی دیگر نسبت به این تغییرات بی تفاوت باشد.



توجه:

بهتر است برای مدیریت تغییر در تنظیمات، بجای attribute فوق از روش های دیگر نظیر فریم ورک loader یا fragment های فاقد UI (headless fragments) استفاده نمایید. در آینده به شرح مفاهیم نام برده خواهیم پرداخت.

ثابت کردن وضعیت نمایش (orientation) یک activity

این امکان برای شما وجود دارد که activity را در فایل تنظیمات AndroidManifest.xml طوری تعریف کنید که فقط در یک وضعیت یا نمای (orientation) خاص نمایش داده شود. برای مثال فایل XML زیر یک activity تعریف کرده که تنها در حالت و نمای افقی (landscape) به کاربر نشان داده می شود.


                    
                    
                    
   

تمرین: بررسی Lifecycle

ایجاد پروژه

یک پروژه ی جدید به نام com.vogella.android.lifecycle.activity ایجاد کنید.
کلاسی با پیاده سازی زیر تعریف کنید که از طریق notification ها، رخدادها یا event های مربوط به چرخه ی حیات را گزارش می کند.

package com.vogella.android.lifecycle.activity;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
public class TracerActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                notify("onCreate");
        }
        @Override
        protected void onPause() {
                super.onPause();
                notify("onPause");
        }
        @Override
        protected void onResume() {
                super.onResume();
                notify("onResume");
        }
        @Override
        protected void onStop() {
                super.onStop();
                notify("onStop");
        }
        @Override
        protected void onDestroy() {
                super.onDestroy();
                notify("onDestroy");
        }
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
               super.onRestoreInstanceState(savedInstanceState);
                notify("onRestoreInstanceState");
        }
        @Override
        protected void onSaveInstanceState(Bundle outState) {
                super.onSaveInstanceState(outState);
                notify("onSaveInstanceState");
        }
        private void notify(String methodName) {
                String name = this.getClass().getName();
                String[] strings = name.split("\\.");
                Notification noti = new Notification.Builder(this)
                 .setContentTitle(methodName + " " + strings[strings.length - 1]).setAutoCancel(true)
                 .setSmallIcon(R.drawable.ic_launcher)
                 .setContentText(name).build();
                NotificationManager notificationManager =
                                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                notificationManager.notify((int) System.currentTimeMillis(), noti);
        }
}

ایجاد activity های مورد نیاز

دو activity دیگر ایجاد کنید که activity بالا را به ارث می برند. Activity اول باید از طریق یک intent، اکتیویتی دوم را راه اندازی کند.

package com.vogella.android.lifecycle.activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends TracerActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }
        public void onClick(View view) {
                Intent intent = new Intent(this, SecondActivity.class);
                startActivity(intent);
        }
}
package com.vogella.android.lifecycle.activity;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class SecondActivity extends TracerActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_second);
        }
}
توجه:

بایستی هر دو activity را در فایل تنظیمات (manifest) تعریف نمایید.

تست اپلیکیشن

اپلیکیشن خود را اجرا کرده و اطمینان حاصل کنید همه چیز طبق برنامه اتفاق می افتد.

تست اپلیکیشن

پس از راه یابی به activity دوم و مشاهده ی محتویات آن، دکمه ی بازگشت را در این activity (صفحه ی دوم اپلیکیشن) فشار دهید. خواهید دید که متد onSaveInstanceState() فراخوانی نشده و به تبع آن وضعیت activity جاری ذخیره نمی شود. می توانید تشریح کنید چرا این متد صدا خورده نمی شود!
حال در activity دوم یا همان صفحه ی دوم اپلیکیشن، دکمه ی home را فشار دهید. خواهید دید که به دنبال این رخداد، متد onSaveInstanceState() صدا خورده شده و وضعیت activity جاری ذخیره می شود. علت فراخوانده شدن این متد را شرح دهید.
حال activity یا صفحه ی دوم اپلیکیشن را اجرا نمایید. جهت نمایش (orientation) محیط شبیه ساز را تغییر داده و دقت کنید که کدام متدهای مربوط به lifecycle صدا زده می شوند. آیا activity اول نیز دوباره ساخته می شود یا فقط activity دوم مجددا راه اندازی می شود.
گزینه ی Don’t keep activities را در بخش تنظیمات مربوط به توسعه دهنده (Developer Options) فعال نمایید. بار دیگر دقت کنید کدام متدها فراخوانده می شوند.

بازگردانی وضعیت نمونه activity

ابتدا آرایه ای از نوع رشته تعریف کرده و سپس یک آبجکت Spinner (لیست کشویی) به activity اول خود اضافه نمایید که مقادیر آن از این آرایه پر می شود. در کد XML زیر، فایل strings.xml و layout مورد استفاده ی activity اول را مشاهده می کنید.



                    Lifecycle
                    Settings
                    Hello world!
                    
                    Ubuntu
                    Android
                    iOS
    


                    
                    

اندروید وضعیت و اطلاعات مربوط به آبجکت Spinner یا همان لیست کشویی را به صورت خودکار بازگردانی می کند. در واقع سیستم اندروید خود وضعیت جاری آبجکت مزبور (همچون انتخاب کاربر) را ذخیره کرده و در صورت تغییر در تنظیمات اپلیکیشن یا دستگاه و همچنین راه اندازی مجدد activity ها (نابود شدن activity و بازسازی آن)، آن را به وضعیت قبلی بازگردانی می کند.
حال مقادیر ثابت آرایه در فایل layout را حذف کرده و آن را در کد برنامه (از طریق source code) به آبجکت Spinner تخصیص دهید.

// configure the spinner in code
Spinner spinner = (Spinner) findViewById(R.id.spinner);
String[] values = getResources().getStringArray(R.array.operating_systems);
ArrayAdapter adapter =
        new ArrayAdapter(this, android.R.layout.simple_list_item_1, values);
spinner.setAdapter(adapter);

مقادیر تخصیص یافته ی ثابت را از فایل layout خود نیز حذف نمایید.


                    
                    

اطمینان حاصل نمایید که وضعیت آبجکت Spinner همچنان مانند قبل به صورت خودکار بازگردانی می شود.

1395/12/04 1995 0
نظرات شما

نظرات خود را ثبت کنید...